﻿using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

namespace ORT
{
    [System.Serializable]
    public class CircleData
    {
        public int id;
        public Vector2 angleA;
        public Vector2 angleB;
        public Vector2 angleC;
        public float specialAngle;
        public float mMinRadius;
        public float mMaxRadius;
    }

    public class Recognition : MonoBehaviour
    {


        public static Recognition instance;
        public Canvas mainCanvas;
        List<GameObject> circleList = new List<GameObject>();
        public List<CircleData> circleDatas;
        public GameObject goDian;
      
        /// <summary>
        /// 检测物体的最大半径
        /// </summary>
        public float maxRadius = 150;
        /// <summary>
        /// 检测物体的最小半径
        /// </summary>
        public float minRadius = 100;
        /// <summary>
        /// 识别物体的实际半径（先用一个物体做测试）
        /// </summary>
        public float trueRadius = 120;
        List<Vector2> posList = new List<Vector2>();
        //圆形的预制体
        public GameObject goCircle;
        //生成的物体信息
        public Dictionary<int, TestCircle> circleDic = new Dictionary<int, TestCircle>();
        //circleDic[1].circlePos 圆心坐标
        //circleDic[1].curAngle  旋转角度

      

        public List<Vector2> allPos = new List<Vector2>();
        private Dictionary<int, bool> showDic = new Dictionary<int, bool>();

        List<GameObject> dianList = new List<GameObject>();

        public delegate void RecognitionID(int id, bool isShow);

        /// <summary>
        /// 识别物体事件
        /// </summary>
        public RecognitionID mRecognitionID = null;


        public delegate void RecognitionIDAngle(int id, float angle);




        bool isGO = false;
        /// <summary>
        /// 物体旋转事件
        /// </summary>
        public RecognitionIDAngle mRecognitionIDAngle = null;


        void Awake()
        {
            instance = this;

            ObjectRecognitionTable.start(Application.streamingAssetsPath);

        }

        // Use this for initialization
        void Start()
        {
           
                initCir();
           

        }

        void initCir()
        {
            maxRadius = ObjectRecognitionTable.maxRadius;
            minRadius = ObjectRecognitionTable.minRadius;
            trueRadius = ObjectRecognitionTable.trueRadius;

            for (int i = 0; i < ObjectRecognitionTable.angleA1.Length; i++)
            {
                CircleData data = new CircleData();
                data.id = ObjectRecognitionTable.circleID[i];
                data.angleA = new Vector2(ObjectRecognitionTable.angleA1[i], ObjectRecognitionTable.angleA2[i]);
                data.angleB = new Vector2(ObjectRecognitionTable.angleB1[i], ObjectRecognitionTable.angleB2[i]);
                data.angleC = new Vector2(ObjectRecognitionTable.angleC1[i], ObjectRecognitionTable.angleC2[i]);
                data.specialAngle = ObjectRecognitionTable.specialAngle[i];
                data.mMinRadius = ObjectRecognitionTable.mMinRadius[i];
                data.mMaxRadius = ObjectRecognitionTable.mMaxRadius[i];
                circleDatas.Add(data);
            }
        }

        // Update is called once per frame
        void Update()
        {
           

            if (Input.touchCount >= 1)
            {
                Debug.Log(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss ffff") + " 当前检测到触摸点：" + Input.touchCount);
                for (int i = 0; i < Input.touchCount; i++)
                {
                    Vector2 _pos = Vector2.one;
                    RectTransformUtility.ScreenPointToLocalPointInRectangle(mainCanvas.transform as RectTransform, Input.GetTouch(i).position, mainCanvas.worldCamera, out _pos);
                    allPos.Add(_pos);
                   
                }
                
                if (!ObjectRecognitionTable.checkTouch)
                    RecognitionShape();
            }
            if (!ObjectRecognitionTable.checkTouch)
            {
                foreach (int id in circleDic.Keys)
                {
                    if (showDic.ContainsKey(id))
                    {
                        circleDic[id].UpdateNoCheckTime(true);
                        if (mRecognitionID != null)
                        {
                            mRecognitionID(id, true);
                        }

                    }
                    else
                    {
                        circleDic[id].UpdateNoCheckTime(false);
                    }
                }
                showDic.Clear();
            }

           
        }

        List<Vector2> tempAllPos = new List<Vector2>();

        void RecognitionDistance()
        {


        }

        /// <summary>
        /// 通过三个点计算圆的半径和圆心点，通过三个点计算出三角形的三个内角，进行物体识别
        /// </summary>
        void RecognitionShape()
        {
            Debug.Log("开始识别：" + circleDic.Count);

            if (circleDic.Count > 0)
            {
                tempAllPos.Clear();
                foreach (int id in circleDic.Keys)
                {
                    CheckCircle(circleDic[id]);
                    int count = tempAllPos.Count;
                    if (count > 0)
                    {
                        if (count == 3)
                        {
                            for (int i = 0; i < 3; i++)
                            {
                                if (allPos.Contains(tempAllPos[i]))
                                    allPos.Remove(tempAllPos[i]);
                            }
                        }
                        else if (count < 3)
                        {
                            if (circleDic[id].gameObject.activeSelf)
                            {
                                if (!showDic.ContainsKey(circleDic[id].circleData.id))
                                    showDic.Add(circleDic[id].circleData.id, true);

                            }
                        }
                    }

                    tempAllPos.Clear();
                    if (allPos.Count < 3)
                    {
                        allPos.Clear();
                        return;
                    }
                }
                if (allPos.Count < 3)
                {
                    allPos.Clear();
                    return;
                }
            }
            if (allPos.Count == 3)
            {
                Vector3 result = Utils.CalRadius(allPos[0], allPos[1], allPos[2]);
                Debug.Log("allPos[0]:" + allPos[0] + "allPos[1]:" + allPos[1] + "allPos[2]:" + allPos[2]);
                Debug.Log(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss ffff") + "  A生成的圆：" + result.ToString() + "半径" + result.z + ":" + minRadius + ":" + maxRadius);
                if (result.z >= minRadius && result.z <= maxRadius)
                {
                    Vector3 result1 = Utils.CalAngles(allPos[0], allPos[1], allPos[2]);
                    Debug.Log(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss ffff") + "  A生成的三角形：" + result1.ToString());
                    int id = CheckID(result1);
                    if (id > 0)
                    {
                        Debug.Log(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss ffff") + "  A识别成功：" + id);
                        Debug.Log("allPos[0]:" + allPos[0] + "allPos[1]:" + allPos[1] + "allPos[2]:" + allPos[2]);
                        Debug.Log(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss ffff") + "  A生成的圆：" + result.ToString() + "半径" + result.z + ":" + minRadius + ":" + maxRadius);

                        AddObj(result, allPos, id, result1);
                        if (!showDic.ContainsKey(id))
                            showDic.Add(id, true);
                        circleDic[id].circlePos = new Vector2(result.x, result.y);

                    }
                }
                allPos.Clear();
            }
            else
            {
                #region
                posList.Clear();
                for (int i = allPos.Count - 1; i >= 0; i--)
                {
                    int id = 0;
                    for (int j = allPos.Count - 2; j >= 0; j--)
                    {
                        if (i == j)
                            continue;
                        for (int k = allPos.Count - 1; k >= 0; k--)
                        {
                            if (i == k)
                                continue;
                            if (j == k)
                                continue;
                            Vector3 result = Utils.CalRadius(allPos[i], allPos[j], allPos[k]);
                            if (result.z >= minRadius && result.z <= maxRadius)
                            {
                                Debug.Log(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss ffff") + " C生成的圆：" + result.ToString());
                                Vector3 result1 = Utils.CalAngles(allPos[i], allPos[j], allPos[k]);
                                Debug.Log(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss ffff") + " C生成的三角形：" + result1.ToString());
                                id = CheckID(result1);
                                if (id > 0)
                                {
                                    Vector2 posA = allPos[i];
                                    Vector2 posB = allPos[j];
                                    Vector2 posC = allPos[k];
                                    posList.Add(posA);
                                    posList.Add(posB);
                                    posList.Add(posC);
                                    Debug.Log(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss ffff") + " C识别成功：" + id);



                                    AddObj(result, posList, id, result1);
                                    if (!showDic.ContainsKey(id))
                                        showDic.Add(id, true);
                                    circleDic[id].circlePos = new Vector2(result.x, result.y);
                                    allPos.Remove(posA);
                                    allPos.Remove(posB);
                                    allPos.Remove(posC);
                                    if (allPos.Count < 3)
                                    {
                                        allPos.Clear();
                                        return;
                                    }
                                    if (i >= 3)
                                        i -= 3;
                                    if (j >= 3)
                                        j -= 2;
                                    if (k >= 3)
                                        k -= 1;
                                    break;
                                }

                            }
                        }
                    }
                }
                #endregion
                allPos.Clear();
            }

        }

        /// <summary>
        /// 检测指定的识别物
        /// </summary>
        /// <param name="circle"></param>
        void CheckCircle(TestCircle circle)
        {
            for (int i = 0; i < allPos.Count; i++)
            {
                if (Vector2.Distance(allPos[i], circle.transform.localPosition) < maxRadius)
                {
                    tempAllPos.Add(allPos[i]);
                }
            }
            if (tempAllPos.Count == 3)
            {
                Vector3 result = Utils.CalRadius(tempAllPos[0], tempAllPos[1], tempAllPos[2]);
                Debug.Log(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss ffff") + " B1生成的圆：" + result.ToString());
                if (result.z >= minRadius && result.z <= maxRadius)
                {
                    Vector3 result1 = Utils.CalAngles(tempAllPos[0], tempAllPos[1], tempAllPos[2]);
                    Debug.Log(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss ffff") + " B1生成的三角形：" + result1.ToString());
                    if (CheckIsMySelf(circle.circleData, result1))
                    {
                        Debug.Log(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss ffff") + " B1识别成功：" + circle.circleData.id);

                        if (!showDic.ContainsKey(circle.circleData.id))
                            showDic.Add(circle.circleData.id, true);
                        if (!circle.gameObject.activeSelf)
                            circle.gameObject.SetActive(true);
                        circle.transform.localPosition = new Vector3(result.x, result.y, 0);
                        circle.SetPoints(tempAllPos, result1, false);
                        circle.circlePos = new Vector2(result.x, result.y);
                        return;
                    }
                }
                return;
            }
            else
            {
                tempAllPos.Clear();
            }

            for (int i = 0; i < allPos.Count; i++)
            {
                for (int j = i + 1; j < allPos.Count; j++)
                {
                    if (i == j)
                        continue;
                    for (int k = j + 1; k < allPos.Count; k++)
                    {
                        if (i == k)
                            continue;
                        if (j == k)
                            continue;
                        Vector3 result = Utils.CalRadius(allPos[i], allPos[j], allPos[k]);
                        if (result.z >= minRadius && result.z <= maxRadius)
                        {
                            Debug.Log(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss ffff") + " B生成的圆：" + result.ToString());

                            Vector3 result1 = Utils.CalAngles(allPos[i], allPos[j], allPos[k]);
                            Debug.Log(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss ffff") + " B生成的三角形：" + result1.ToString());

                            if (CheckIsMySelf(circle.circleData, result1))
                            {
                                Debug.Log(allPos[i].ToString() + "   " + allPos[j] + "    " + allPos[k]);
                                tempAllPos.Add(allPos[i]);
                                tempAllPos.Add(allPos[j]);
                                tempAllPos.Add(allPos[k]);
                                Debug.Log(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss ffff") + " B识别成功：" + circle.circleData.id);

                                if (!showDic.ContainsKey(circle.circleData.id))
                                    showDic.Add(circle.circleData.id, true);



                                if (!circle.gameObject.activeSelf)
                                    circle.gameObject.SetActive(true);
                                circle.transform.localPosition = new Vector3(result.x, result.y, 0);
                                circle.SetPoints(tempAllPos, result1, false);
                                circle.circlePos = new Vector2(result.x, result.y);
                                return;
                            }
                        }
                    }
                }
            }

            if (tempAllPos.Count == 0)
            {
                for (int i = 0; i < allPos.Count; i++)
                {
                    if (Vector2.Distance(allPos[i], circle.transform.localPosition) < maxRadius)
                    {
                        tempAllPos.Add(allPos[i]);
                    }
                }
            }
        }


        /// <summary>
        /// 添加生成的圆到字典里
        /// </summary>
        /// <param name="result"></param>
        /// <param name="pos"></param>
        /// <param name="id"></param>
        void AddObj(Vector3 result, List<Vector2> pos, int id, Vector3 angles)
        {
            TestCircle circle = null;
            if (circleDic.ContainsKey(id))
            {
                circle = circleDic[id];
            }
            if (circle == null)
            {
                GameObject go = Instantiate(goCircle);
                go.transform.parent = transform;
                go.transform.localScale = Vector3.one;
                go.transform.localPosition = new Vector3(result.x, result.y, 0);


                circle = go.GetComponent<TestCircle>();
                circle.circlePos = new Vector2(result.x, result.y);
                circle.thisTransform = circle.transform;
                circle.m_Radius = result.z;
                circle.SetID(circleDatas[id - 1]);
                circle.SetPoints(pos, angles, true);
                circleDic.Add(id, circle);
                if (mRecognitionID != null)
                {
                    mRecognitionID(id, true);
                }
            }
            else
            {
                circle.gameObject.SetActive(true);
                circle.transform.localPosition = new Vector3(result.x, result.y, 0);
                circle.SetPoints(pos, angles, false);
               
            }
        }

        public void HideCurCircle(int id)
        {
            if (circleDic.ContainsKey(id))
            {
                circleDic[id].UIHideMe();
            }
        }

        void AddDian(Vector2 pos, int i)
        {
            GameObject go = null;
            if (i < dianList.Count)
            {
                go = dianList[i];
                go.SetActive(true);
            }
            else
            {
                go = Instantiate(goDian);
                go.transform.parent = transform;
                dianList.Add(go);
            }
            go.transform.localPosition = pos;
            go.transform.localScale = Vector3.one;

        }

        int count = 0;

       
        bool CheckIsMySelf(CircleData data, Vector3 angle)
        {
            if (((angle.x >= data.angleA.x && angle.x <= data.angleA.y) &&
                      (angle.y >= data.angleB.x && angle.y <= data.angleB.y) &&
                      (angle.z >= data.angleC.x && angle.z <= data.angleC.y)) ||
                      ((angle.x >= data.angleA.x && angle.x <= data.angleA.y) &&
                      (angle.z >= data.angleB.x && angle.z <= data.angleB.y) &&
                      (angle.y >= data.angleC.x && angle.y <= data.angleC.y)) ||
                      ((angle.z >= data.angleA.x && angle.z <= data.angleA.y) &&
                      (angle.y >= data.angleB.x && angle.y <= data.angleB.y) &&
                      (angle.x >= data.angleC.x && angle.x <= data.angleC.y)) ||
                      ((angle.z >= data.angleA.x && angle.z <= data.angleA.y) &&
                      (angle.x >= data.angleB.x && angle.x <= data.angleB.y) &&
                      (angle.y >= data.angleC.x && angle.y <= data.angleC.y)) ||
                      ((angle.y >= data.angleA.x && angle.y <= data.angleA.y) &&
                      (angle.x >= data.angleB.x && angle.x <= data.angleB.y) &&
                      (angle.z >= data.angleC.x && angle.z <= data.angleC.y)) ||
                      ((angle.y >= data.angleA.x && angle.y <= data.angleA.y) &&
                      (angle.z >= data.angleB.x && angle.z <= data.angleB.y) &&
                      (angle.x >= data.angleC.x && angle.x <= data.angleC.y)))
            {
                return true;
            }
            return false;
        }

        /// <summary>
        /// 对比角度，识别对应物体的ＩＤ
        /// </summary>
        /// <param name="angle"></param>
        /// <returns></returns>
        int CheckID(Vector3 angle)
        {
            int id = 0;
            for (int i = 0; i < circleDatas.Count; i++)
            {
                CircleData data = circleDatas[i];
                if (data == null)
                    continue;
                if (((angle.x >= data.angleA.x && angle.x <= data.angleA.y) &&
                             (angle.y >= data.angleB.x && angle.y <= data.angleB.y) &&
                             (angle.z >= data.angleC.x && angle.z <= data.angleC.y)) ||
                             ((angle.x >= data.angleA.x && angle.x <= data.angleA.y) &&
                             (angle.z >= data.angleB.x && angle.z <= data.angleB.y) &&
                             (angle.y >= data.angleC.x && angle.y <= data.angleC.y)) ||
                             ((angle.z >= data.angleA.x && angle.z <= data.angleA.y) &&
                             (angle.y >= data.angleB.x && angle.y <= data.angleB.y) &&
                             (angle.x >= data.angleC.x && angle.x <= data.angleC.y)) ||
                             ((angle.z >= data.angleA.x && angle.z <= data.angleA.y) &&
                             (angle.x >= data.angleB.x && angle.x <= data.angleB.y) &&
                             (angle.y >= data.angleC.x && angle.y <= data.angleC.y)) ||
                             ((angle.y >= data.angleA.x && angle.y <= data.angleA.y) &&
                             (angle.x >= data.angleB.x && angle.x <= data.angleB.y) &&
                             (angle.z >= data.angleC.x && angle.z <= data.angleC.y)) ||
                             ((angle.y >= data.angleA.x && angle.y <= data.angleA.y) &&
                             (angle.z >= data.angleB.x && angle.z <= data.angleB.y) &&
                             (angle.x >= data.angleC.x && angle.x <= data.angleC.y)))
                {
                    id = circleDatas[i].id;
                    //      Debug.Log("当前识别的的id：" + id);
                    break;
                }
            }
            return id;
        }

        int CheckID(Vector3 angle, int oid)
        {
            int id = 0;
            for (int i = 0; i < circleDatas.Count; i++)
            {
                CircleData data = circleDatas[i];
                if (data == null)
                    continue;
                if (data.id == oid)
                    continue;
                if (((angle.x >= data.angleA.x && angle.x <= data.angleA.y) &&
                             (angle.y >= data.angleB.x && angle.y <= data.angleB.y) &&
                             (angle.z >= data.angleC.x && angle.z <= data.angleC.y)) ||
                             ((angle.x >= data.angleA.x && angle.x <= data.angleA.y) &&
                             (angle.z >= data.angleB.x && angle.z <= data.angleB.y) &&
                             (angle.y >= data.angleC.x && angle.y <= data.angleC.y)) ||
                             ((angle.z >= data.angleA.x && angle.z <= data.angleA.y) &&
                             (angle.y >= data.angleB.x && angle.y <= data.angleB.y) &&
                             (angle.x >= data.angleC.x && angle.x <= data.angleC.y)) ||
                             ((angle.z >= data.angleA.x && angle.z <= data.angleA.y) &&
                             (angle.x >= data.angleB.x && angle.x <= data.angleB.y) &&
                             (angle.y >= data.angleC.x && angle.y <= data.angleC.y)) ||
                             ((angle.y >= data.angleA.x && angle.y <= data.angleA.y) &&
                             (angle.x >= data.angleB.x && angle.x <= data.angleB.y) &&
                             (angle.z >= data.angleC.x && angle.z <= data.angleC.y)) ||
                             ((angle.y >= data.angleA.x && angle.y <= data.angleA.y) &&
                             (angle.z >= data.angleB.x && angle.z <= data.angleB.y) &&
                             (angle.x >= data.angleC.x && angle.x <= data.angleC.y)))
                {
                    id = circleDatas[i].id;
                    break;
                }
            }
            return id;
        }
    }

}
